package org.xxpay.pay.channel.jimu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.unify.AbstractPaymentConfig;
import org.xxpay.common.util.DateUtils;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;

import java.util.Date;
import java.util.Map;

/**
 * @Package org.xxpay.pay.channel.jimu
 * @Class: JimupayPaymentService.java
 * @Description:
 * @Author leo
 * @Date 2019/4/9 20:13
 * @Version
 **/
@Component
public class JimupayPaymentService extends BasePayment {

    private final static String logPrefix = "【吉沐支付】";

    @Override
    public String getChannelName() {
        return JimupayConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject pay(PayOrder payOrder) {
        String channelId = payOrder.getChannelId();
        JSONObject retObj;
        switch (channelId) {
            case JimupayConfig.CHANNEL_NAME_ALIPAY:
                retObj = doOrderReq(payOrder);
                break;
            default:
                retObj = buildRetObj(PayConstant.RETURN_VALUE_FAIL, "不支持的渠道[channelId="+channelId+"]");
                break;
        }
        return retObj;
    }

    private JSONObject doOrderReq(PayOrder payOrder) {
        JimupayConfig jimupayConfig = new JimupayConfig(getPayParam(payOrder));
        // 请求参数
        Map<String, Object> parameters = Maps.newHashMap();
        parameters.put("MerId", jimupayConfig.getMchId());
        parameters.put("PayType", jimupayConfig.getPayMode());
        parameters.put("MerOrderNo", payOrder.getPayOrderId());
        parameters.put("MerOrderTime", DateUtils.YYYYMMDDHHMMSS.format(new Date()));
        parameters.put("Amount", payOrder.getAmount());
        parameters.put("NotifyUrl", payConfig.getNotifyUrl(getChannelName()));
        parameters.put("SuccessUrl", payConfig.getReturnUrl());
        parameters.put("Sign", getSign(jimupayConfig, parameters));
        _log.info("{}请求参数：{}", logPrefix, JSON.toJSONString(parameters));
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(getReqUrl(jimupayConfig.getRequestUrl(), JimupayConfig.REQUEST_CREATE_ORDER),
                parameters, JSONObject.class);
        _log.info("{}同步请求响应参数：{}", logPrefix, origin.toJSONString());
        // 响应对象
        JSONObject retObj = new JSONObject();

        if(StringUtils.equals(origin.getString("code"), JimupayConfig.RETURN_VALUE_SUCCESS)) {
            JSONObject bizContext = origin.getJSONObject("data");
            // 渠道订单号
            String channelOrderNo = bizContext.getString("PayOrderNo");
            // 将订单更改为支付中
            int result = rpcCommonService.rpcPayOrderService.updateStatus4Ing(payOrder.getPayOrderId(), channelOrderNo);
            _log.info("[{}]更新订单状态为支付中:payOrderId={},channelOrderNo={},result={}", getChannelName(), payOrder.getPayOrderId(), channelOrderNo, result);
            // 支付链接地址
            String codeUrl = bizContext.getString("PayUrl");
            return buildPayResultOfCodeURL(retObj, payOrder, codeUrl);
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("message"));
        return retObj;
    }


    private String getSign(AbstractPaymentConfig config, Map<String, Object> parameters) {
        StringBuffer buffer = new StringBuffer()
                .append(parameters.get("Amount")).append("|")
                .append(parameters.get("MerOrderNo")).append("|")
                .append(parameters.get("MerOrderTime")).append("|")
                .append(config.getPrivateKey());


        String signTxt = buffer.toString();
        String firstSign = SignUtils.MD5.createSign(signTxt, "", SignUtils.CHARSET_UTF8).toUpperCase();
        String signValue = SignUtils.MD5.createSign(firstSign, "", SignUtils.CHARSET_UTF8).toUpperCase();
        return signValue;
    }

}
